import React, { useEffect, useRef, useState } from 'react'
import './index.less'
import { max, min, ecg_data } from './data.js'

const Ecg = () => {
    let ctx = null
    let zoomY = 1 // 纵坐标两点之间的缩放比例
    let intervalX = 5 // 横坐标两点之间的间隔数值
    let interval = 60 // 定时器时间间隔
    let points = 8 // 一个定时器间隔的绘制的点数
    let k = 0

    let arr = []
    const [intervalId, setIntervalId] = useState(null)
    const [canvasWidth, setCanvasWidth] = useState(0)
    const [canvasHeight, setCanvasHeight] = useState(0)
    const canvasRef = useRef()
    const wrapRef = useRef()

    useEffect(() => {
        if (wrapRef.current) {
            const { width, height } = wrapRef.current.getBoundingClientRect()
            setCanvasWidth(width)
            setCanvasHeight(height)

            const resizeObserver = new ResizeObserver((entries) => {
                console.log('resize: ', entries)
                const { width, height } = entries[0].target.getBoundingClientRect()
                setCanvasWidth(width)
                setCanvasHeight(height)
            })

            resizeObserver.observe(wrapRef.current)
        }
    }, [wrapRef])

    useEffect(() => {
        if (canvasWidth > 0 && canvasHeight > 0) {
            ctx = canvasRef.current.getContext('2d')
            draw()
        }
    }, [canvasWidth, canvasHeight])

    useEffect(() => {
        return () => {
            intervalId && clearInterval(intervalId)
        }
    }, [intervalId])

    /**
     * 获取曲线缩放比
     */
    function getScale() {
        const chartsHeight = Math.abs(max - min)
        // 画布和图像的差值
        let heightDiff = canvasHeight - chartsHeight
        if (heightDiff < 0) {
            zoomY = Math.ceil(chartsHeight / canvasHeight)
        }
    }

    function moveToCenter() {
        let newMax = (canvasHeight - min) / zoomY
        let newMin = (canvasHeight - max) / zoomY
        let diff = newMax - newMin
        let y = 0
        if (newMin < 0) {
            // 图像部分画布的上面
            y = Math.abs(newMin) + (canvasHeight - diff) / 2
        } else {
            // 图像显示在画布范围内
            y = (canvasHeight - diff) / 2 - diff / 2
        }
        let z = 1
        if (min >= 0) {
            z = min / zoomY > canvasHeight / 2 ? 1 : -1
        }
        return y * z
    }

    /**
     *
     * @param {number} y
     * @returns
     */
    function getY(y) {
        // console.log('getY', min / zoomY, canvasHeight)
        const v = (canvasHeight - y) / zoomY + moveToCenter()
        return v
    }

    function getX(i) {
        const v = intervalX * i
        return v
    }

    /**
     *
     * @param {number} i
     * @param {number} interval 间隔量
     * @returns
     */
    function clearX(i, interval = 20) {
        return getX(i) + interval
    }

    function setPoints() {
        const len = arr.length
        if (len < 120) {
            points = 4
        } else if (len > 200) {
            points = 12
        } else {
            points = 6
        }
        return points
    }

    function draw() {
        intervalId && clearInterval()

        getScale()
        ctx.beginPath()
        let lastX = 0
        let lastY = getY(arr[0])
        const id = setInterval(() => {
            if (arr.length > 0) {
                for (let i = 0; i < setPoints(); i++) {
                    let v = arr.shift()
                    // console.log('arr', arr.length)
                    let x = getX(k)
                    let y = getY(v)
                    if (x > canvasWidth) {
                        // 从左开始绘制
                        k = 0
                        x = getX(k)

                        ctx.beginPath()
                        // 重新定位到最左边的坐标
                        ctx.moveTo(x, y)
                    } else {
                        ctx.moveTo(lastX, lastY)
                    }
                    ctx.lineTo(x, y)
                    lastX = x
                    lastY = y
                    ctx.clearRect(0, 0, clearX(k), canvasHeight)
                    ctx.stroke()
                    k++
                }
            }
        }, interval)
        setIntervalId(id)
    }

    setInterval(() => {
        arr = arr.concat(ecg_data)
    }, 1000)

    return (
        <div ref={wrapRef} className="wrap">
            <canvas ref={canvasRef} width={canvasWidth} height={canvasHeight} className="myCanvas">
                您的浏览器不支持 HTML5 canvas 标签。
            </canvas>
        </div>
    )
}
export default Ecg
